#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> //close()
#include <string.h> 
#include <stdlib.h> //atoi() 字符串转int
#include <sys/time.h>
#include <errno.h>
#include <pthread.h>
#include<signal.h>

void test_time();
void send_client_current_time(int socket_cli_fd);
void* receive_from_server();
void print_err(char* str, int line, int err_no);
void set_cli_sys_time();
void create_socket_and_connect(char *s);


typedef struct
{
	double sec;
	double usec;
}mytime;


struct timeval start, end;
mytime start_d,end_d,temp;

int socket_fd = -1; /* client only has one socket file descript */
int port = 5050;


int main(int argc, char* argv[])
{
	set_cli_sys_time();
	signal(SIGPIPE, SIG_IGN); /*  Ignore the signal  to end the program */

	printf("server IP : %s\n",argv[1]);
	char exe[100] = "";
	snprintf(exe,100,"ntpdate %s",argv[1]);
	printf("exe : %s\n",exe);
	//pthread_t id, send_id;
	//pthread_create(&id, NULL, receive_from_server, NULL);/* client 接收 server time 线程 */
	
	while (1)
	{
		system(exe);
		sleep(8);
		create_socket_and_connect(argv[1]);
		send_client_current_time(socket_fd);
		receive_from_server();/*receive then close the socket */
	}

	close(socket_fd);
	return 0;
}

void client_loop_cur_time()
{

}

void send_client_current_time(int socket_cli_fd)
{
	char sendbuf[1024] = "";
	char *p = sendbuf;
	char *pp = sendbuf;
	gettimeofday(&start, NULL);
	//printf("Client  发送过去的时间秒数是：%ld  s,  毫秒数是：%ld  us\n", start.tv_sec, start.tv_usec);	
	start_d.sec = start.tv_sec;
	start_d.usec = start.tv_usec;
	memcpy(p, (char *)&start_d, sizeof(start_d));
	//struct timeval* ppt = (struct timeval*)pp;
	
	int ret = send(socket_cli_fd,sendbuf, sizeof(sendbuf), 0);
	
	if (-1 == ret) {
		print_err("Cli send failed", __LINE__, errno);
	}else{
		//printf("Client现在的时间秒数是：%ld  ,  %lf毫秒数是：%ld , %lf\n",start.tv_sec,start_d.sec,start.tv_usec,start_d.usec);
		printf("Client 发送过去的时间秒数是：%lf  s,  毫秒数是：%lf  us\n", start_d.sec, start_d.usec);	

	}

}

void* receive_from_server()
{
	int ret = 0;
	char recvbuf[1024] = "";
	bzero(&end, sizeof(end));
	ret = recv(socket_fd, recvbuf, sizeof(recvbuf), 0);
	//recv(sockConn, recvbufFromSer, sizeof(recvbufFromSer),MSG_WAITALL)
	if (ret < 0) {
			print_err("recv failed", __LINE__, errno);
	}
	else {
			gettimeofday(&end, NULL);
			char *p  = recvbuf;
			mytime* pp = (mytime *)p;
			
			printf("Server 发送过来的时间秒数是：%lf  s,  毫秒数是：%lf us\n",pp->sec, pp->usec);	
			//printf("Client 发送过去的时间秒数是：%ld  s,  毫秒数是：%ld  us\n", start.tv_sec, start.tv_usec);			
			//(end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec);
			//double fi = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0;
			double ff = pp->usec / 1000.0 + pp->sec * 1000 - start.tv_usec /1000.0 - start.tv_sec * 1000.0;
			printf("sigle transport time offset : %lf ms\n", ff);
			printf("************************************************************\n\n");
			sleep(2);
			close(socket_fd);
	
	}
	//gettimeofday(&end, NULL);

}

void create_socket_and_connect(char *s)
{
		//1 创建tcp通信socket
		int value = 1;
		socket_fd = socket(AF_INET, SOCK_STREAM, 0);
		if (socket_fd == -1)
		{
			perror("socket failed!\n");
		}
		setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&value,sizeof(value));
		//2 连接服务器
		struct sockaddr_in server_addr = { 0 };
		
		server_addr.sin_family = AF_INET;//IPv4协议
		server_addr.sin_port = htons(port);//服务器端口号
		server_addr.sin_addr.s_addr = inet_addr(s);//inet_addr("192.168.0.3");//设置服务器IP// 127.0.0.1
		int ret = connect(socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
		if (ret == -1)
		{
			perror("connect failed!\n");
		}
		else
		{
			printf("connect server successful!\n");
		}
}


void set_cli_sys_time()
{
	
	struct timeval stime;
	stime.tv_sec =1599719331;
	stime.tv_usec =123;
	if(settimeofday(&stime,NULL) == 0)
	{
	printf("Set cli time success\n");
	sleep(1);
	gettimeofday(&stime, NULL);
	temp.sec = stime.tv_sec;
	temp.usec = stime.tv_usec;
	printf("Client现在的时间秒数是：%ld , %lf毫秒数是：%ld , %lf\n",stime.tv_sec,temp.sec,stime.tv_usec,temp.usec);
	}
}

void print_err(char* str, int line, int err_no) {
	printf("%d, %s :%s\n", line, str, strerror(err_no));
	_exit(-1);
}



void test_time()
{

	gettimeofday(&start, NULL);
	long int ti = (start.tv_sec * 1000000 + start.tv_usec);
	printf("Client 发送过去的时间 : %ld us\n", ti);
	char buf[1024] = { 0 };
	memcpy(buf, &start, sizeof(start));
	struct timeval* temp = (struct timeval*)buf;
	ti = (temp->tv_sec * 1000000 + temp->tv_usec);
	printf("time offset : %ld\n", ti);

}

